package jcode.mybatismapper.base;

import org.apache.ibatis.annotations.*;
import org.apache.ibatis.builder.annotation.ProviderContext;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;

@Mapper
public interface BaseDao<T, ID> {

    @SelectProvider(type = BaseDaoProvider.class, method = "get")
    T get(ID id);

    @InsertProvider(type = BaseDaoProvider.class, method = "insert")
    void insert(T entity);

    @UpdateProvider(type = BaseDaoProvider.class, method = "updateByAnnotation")
    void updateByAnnotation(T entity, Class<? extends Annotation> updateAnnotation);

    @DeleteProvider(type = BaseDaoProvider.class, method = "delete")
    void delete(ID id);

    public static class BaseDaoProvider {

        private Class ModelType(ProviderContext providerContext) {
            Class mapperType = providerContext.getMapperType();
            ParameterizedType genericSuperclass = (ParameterizedType)mapperType.getGenericInterfaces()[0];
            return (Class) genericSuperclass.getActualTypeArguments()[0];
        }

        public String get(ProviderContext providerContext) {
            Class entityClass = ModelType(providerContext);
            return EntitySQL.from(entityClass).getSQL();
        }

        public String insert(ProviderContext providerContext) {
            Class entityClass = ModelType(providerContext);
            return EntitySQL.from(entityClass).insertSQL();
        }

        public String delete(ProviderContext providerContext) {
            Class entityClass = ModelType(providerContext);
            return EntitySQL.from(entityClass).deleteSQL();
        }

        public String updateByAnnotation(Object entity, Class<? extends Annotation> updateAnnotation, ProviderContext providerContext) {
            Class entityClass = ModelType(providerContext);
            return EntitySQL.from(entityClass).updateByAnnotationSQL(updateAnnotation, "param1.");
        }

    }

}
